﻿using AutoTest.Common;
using AutoTest.Common.Extension;
using AutoTest.Domain.Options;
using AutoTest.Framework.Pager;
using Microsoft.Extensions.Configuration;
using SqlSugar;

namespace AutoTest.Repository.RepositoryExtension
{
    /// <summary>
    /// Sqlsugar扩展方法
    /// </summary>
    public static class SqlsugarExtensions
    {
        /// <summary>
        /// 分页查询 - 扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageSize"></param>
        /// <returns></returns>
        public static async Task<(List<T>, int)> ToPageListAsync<T>(this ISugarQueryable<T> query, int pageIndex, int pageSize)
        {
            var total = new RefAsync<int>();
            var pagedDataList = await query.ToPageListAsync(pageIndex, pageSize, total);
            return (pagedDataList, total);
        }

        /// <summary>
        /// 分页查询 - 扩展
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="query"></param>
        /// <param name="pageSearchDto"></param>
        /// <returns></returns>
        public static async Task<(List<T>, int)> ToPageListAsync<T>(this ISugarQueryable<T> query, IPagedSearchDto pageSearchDto)
        {
            return await query.ToPageListAsync<T>(pageSearchDto.PageIndex, pageSearchDto.PageSize);
        }


        /// <summary>
        /// 数据库配置
        /// </summary>
        /// <param name="configuration"></param>
        /// <param name="configId"></param>
        /// <returns></returns>
        public static DatabaseOption GetDatabase(this IConfiguration configuration, string configId)
        {
            var option = new DatabaseOption(configId);
            configuration.GetSection(configId).Bind(option);
            return option;
        }

        /// <summary>
        /// 转成SqlSugar的连接配置
        /// </summary>
        /// <param name="option"></param>
        /// <returns></returns>
        /// <exception cref="NotSupportedException"></exception>
        public static ConnectionConfig ToConnectionConfig(this DatabaseOption option, bool IsAutoCloseConnection = true)
        {
            var config = new ConnectionConfig
            {
                ConfigId = option.ConfigId,
                ConnectionString = option.GetConnectionString(),
                IsAutoCloseConnection = IsAutoCloseConnection,
                DbType = option.DBType switch
                {
                    "Oracle" => DbType.Oracle,
                    "MySql" => DbType.MySql,
                    "PostgreSQL" => DbType.PostgreSQL,
                    "SqlServer" => DbType.SqlServer,
                    "Sqlite" => DbType.Sqlite,
                    _ => throw new NotSupportedException($"暂不支持【{option.DBType}】")
                }
            };

            if ((option.Slaves?.Count ?? 0) > 0)
            {
                config.SlaveConnectionConfigs = option?.Slaves?.Select(t => new SlaveConnectionConfig()
                {
                    ConnectionString = t.GetConnectionString(),
                    HitRate = t.HitRate ?? 100
                }).ToList()??[];
            }

            return config;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="dbClient"></param>
        /// <param name="configId"></param>
        /// <returns></returns>
        public static ISqlSugarClient GetDatabaseByConfig(this ISqlSugarClient dbClient, string configId)
        {
            return (dbClient as SqlSugarScope)?.GetConnectionScope(configId).CopyNew()!;
        }
        /// <summary>
        /// /
        /// </summary>
        /// <returns></returns>
        public static async Task<string> GetConnectionStringAsync(this DatabaseOption option)
        {
            // return ConnectionFormat?.ReplaceForDict(this.ToDictionary()) ?? "";
            return await (option.ConnectionFormat ?? SqlSugarHelper.GetConnectionStringFormat(option.DBType)).ReplaceForDict(option.ToDictionary()).TemplateRenderAsync(option);
        }
        /// <summary>
        /// /
        /// </summary>
        /// <returns></returns>
        public static string GetConnectionString(this DatabaseOption option)
        {
            // return ConnectionFormat?.ReplaceForDict(this.ToDictionary()) ?? "";
            return (option.ConnectionFormat ?? SqlSugarHelper.GetConnectionStringFormat(option.DBType)).ReplaceForDict(option.ToDictionary()).TemplateRenderAsync(option).GetAwaiter().GetResult();
        }
    }
}
